﻿using Ewk.Math.Algebra.Algorithms.Matrices.Determinant;
using Ewk.Math.Algebra.UnitTests.MatrixTests;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Ewk.Math.Algebra.UnitTests.Algorithms.Matrices
{
    [TestClass]
    public class LaplaceDeterminantFormulaTests : MatrixUnitTestsBase<double>
    {
        LaplaceDeterminantFormula<double> _computer;

        protected override void AdditionalSetup()
        {
            base.AdditionalSetup();

            _computer = new LaplaceDeterminantFormula<double>();
        }

        #region Determinant

        [TestMethod]
        public void LaplaceFormula_for_Determinant_returns_null_when_the_matrix_is_null()
        {
            var determinant = _computer.ComputeDeterminant(null);

            Assert.IsNull(determinant);
        }

        [TestMethod]
        public void MatrixDouble_ComputeDeterminant_does_not_use_an_IDeterminantComputer_when_the_matrix_is_not_a_square_matrix_and_returns_the_zero_representation()
        {
            /* Matrix 1
                    1   2   3   4   5
                    ------------------
                1 | 1   2   3   4   5
                2 | 2   4   6   8   10
                3 | 3   6   9   12  15
            */

            const int rowCount = 3;
            const int columnCount = 5;
            var matrix1 = CreateMatrix(rowCount, columnCount, (i, j) => (i + 1) * (j + 1));

            var determinant = _computer.ComputeDeterminant(matrix1);

            Assert.AreEqual(0, determinant.Value);
        }

        [TestMethod]
        public void LaplaceFormula_for_Determinant_computes_the_determinant_of_the_matrix_3()
        {
            /* Matrix 1
                    1   2   3
                    ---------
                1 | 1   0   0
                2 | 0   1   0
                3 | 0   0   1
            */

            const int m = 3;
            var matrix1 = Matrix<double>.Identity(m);

            var determinant = _computer.ComputeDeterminant(matrix1);

            Assert.AreEqual(1, determinant.Value);
        }

        [TestMethod]
        public void LaplaceFormula_for_Determinant_computes_the_determinant_of_the_matrix_4()
        {
            /* Matrix 1
                    1   2   3   4
                    -------------
                1 | 1   0   0   0
                2 | 0   1   0   0
                3 | 0   0   1   0
                3 | 0   0   0   1
            */

            const int m = 4;
            var matrix1 = Matrix<double>.Identity(m);

            var determinant = _computer.ComputeDeterminant(matrix1);

            Assert.AreEqual(1, determinant.Value);
        }

        [TestMethod, Ignore]
        public void LaplaceFormula_for_Determinant_computes_the_determinant_of_the_matrix_10()
        {
            /* Matrix 1
                    1   2   3   .   n
                    -----------------
                1 | 1   2   3   .   .
                2 | 2   4   6   .   .
                3 | 3   6   9   .   .
                . | .   .   .   .   .
                n | .   .   .   .   x
            */

            const int m = 10;
            var matrix1 = CreateMatrix(m, m, (i, j) => (i + 1) * (j + 1));

            var determinant = _computer.ComputeDeterminant(matrix1);

            Assert.AreEqual(0, determinant.Value);
        }

        #endregion
    }
}